package com.watson.todolist;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Date;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.google.gson.Gson;
import com.watson.todolist.constants.DatabaseConstants;
import com.watson.todolist.database.DatabaseManager;
import com.watson.todolist.database.ToDoListManager;
import com.watson.todolist.location.GoogleReverseGeocodeDAO;
import com.watson.todolist.to.TodoItem;
import com.watson.todolist.to.TodoListAccount;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.DatePicker.OnDateChangedListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

/**
 * This class handles adding todo items to todo list
 * 
 * @author Donnie Ward
 * 
 * @since 1.0
 * 
 */
public class EditTodoItemActivity extends Activity {

	private static String TAG = "EditTodoItemActivity Class";
	private double latitude = -1;
	private double longitude = -1;
	
	/**
	 * This method is called when the activity is created.
	 * 
	 * @param savedInstanceState
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.edit_to_do_item_layout);
		
		// retrieving todoitem information
		DatabaseManager dbManager = new DatabaseManager();
		SQLiteDatabase db = dbManager.open(getApplicationContext());
		ToDoListManager todoListManager = new ToDoListManager(db);
				
		Intent i = this.getIntent();
		final long todoItemid = i.getLongExtra("ToDoItemLongId", -1);		
		
		TodoItem currentItem = todoListManager.getTodoListItemByTodoId(todoItemid);
		
		// checks to see if item is checked or not
		String itemName = currentItem.getTodoItemName();
		String itemDesc = currentItem.getDescription();
		int categoryCode = currentItem.getTodoItemCategoryCode();
		int recurrenceCode = currentItem.getAlarmRecurrenceType();
		long timePrior = currentItem.getPriorAlarmReminderTime();
		long timeCode = currentItem.getTodoTime();
		float latitude = currentItem.getLatitude();
		float longitude = currentItem.getLongitude();
		String location = "";
		List<Address> list;
		
		// sets the name of the to do item to what it originally was
		EditText nameFeild = (EditText) findViewById(R.id.nameOfTodoField);
		nameFeild.setText(itemName, TextView.BufferType.EDITABLE);
		
		// sets the description of the to do item to what it originally was
		EditText descFeild = (EditText) findViewById(R.id.descriptionOfTodoField);
		descFeild.setText(itemDesc, TextView.BufferType.EDITABLE);
		
		// get location and set it to the original one
		
//		try {
//			list = gc.getFromLocation((double)latitude, (double)longitude, 5);
//			if(list.size() != 0 && list != null) {
//				location = list.get(0).getAddressLine(0);
//			}
//		} catch (IOException e1) {
//			// TODO Auto-generated catch block
//			e1.printStackTrace();
//		}
		
		EditText locationFieldOut = (EditText) findViewById(R.id.location);
		
		locationFieldOut.setOnFocusChangeListener(new OnFocusChangeListener() {

			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				setUpLocation(hasFocus);
			}
		});
		
		EditText locationFeild = (EditText)	findViewById(R.id.location);
		locationFeild.setText(currentItem.getLatitude()+","+currentItem.getLongitude());
		
		// sets the category code that was originally of the to do item
		Spinner category = (Spinner) findViewById(R.id.selectCategory);
		category.setSelection(categoryCode);
		
		// sets the recurrence of the original todoitem
		Spinner recurrence = (Spinner) findViewById(R.id.selectRecurrance);
		recurrence.setSelection(recurrenceCode);
		
		// sets the date and time that were original to the todoitem
		DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
		TimePicker timePicker = (TimePicker) findViewById(R.id.timePicker);
		Date date = new Date(timeCode);
		
		
		OnDateChangedListener dateListener = new OnDateChangedListener() {
			
			@Override
			public void onDateChanged(DatePicker view, int year, int monthOfYear,
					int dayOfMonth) {
				// TODO Auto-generated method stub
				
			}
		};
		
		datePicker.init(date.getYear(), date.getMonth(), date.getDay(), dateListener);
		timePicker.setCurrentHour(date.getHours());
		timePicker.setCurrentMinute(date.getMinutes());
		
		Spinner alarmPriorInterval = (Spinner) findViewById(R.id.selectAlarmIncremment);
		Spinner alarmPriorIntervalAmount = (Spinner) findViewById(R.id.alarmTimePicker);
		
		
		
		short intervalSet = -1;
		short daysCheck = (short) (timePrior % (1000*60*60*24));
		short hoursCheck = (short) (timePrior % (1000*60*60));
		short minutesCheck = (short) (timePrior % (1000*60));
		if(daysCheck == 0){
			intervalSet = 2;
			timePrior = timePrior /(1000*60*60*24);
			
		}else if(hoursCheck == 0){
			intervalSet = 1;
			timePrior = timePrior /(1000*60*60);
		}else if(minutesCheck == 0){
			intervalSet = 0;
			timePrior = timePrior /(1000 * 60);
		}
		
		alarmPriorIntervalAmount.setSelection((int) timePrior - 1);
		alarmPriorInterval.setSelection(intervalSet);
	
		
		
		/**
		 * set the initial alarm/date time here... but how do i retrieve those from db?
		 * datePicker.init(year, monthOfYear, dayOfMonth, onDateChangedListener);
		 * 
		 * set the initial time  here... how to retrieve?
		 * timePicker.setCurrentHour(currentHour);
		 * timePicker.setCurrentMinute(currentMinute);
		 */
		
		dbManager.close();
		
		Button submit = (Button) findViewById(R.id.addTodoSubmitButton);
		Button cancel = (Button) findViewById(R.id.addTodoCancelButton);

		// Setting range of number picker (for alarm)
		// Unable to do this in the xml file
		Object picker = findViewById(R.id.alarmTimePicker);
		Class c = picker.getClass();
		try {
			Method m = c.getMethod("setRange", int.class, int.class);
			m.invoke(picker, 1, 100);
		} catch (Exception e) {
			Log.e("", e.getMessage());
		}

		// Set up cancel button listener
		cancel.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent myIntent = new Intent(v.getContext(),
						todoListActivity.class);
				startActivityForResult(myIntent, 3);
			}
		});

		// Set up submit button listener
		submit.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {

				// various check boxes
				// CheckBox dateCheck = (CheckBox) findViewById(R.id.checkDate);
				// CheckBox timeCheck = (CheckBox) findViewById(R.id.checkTime);
				// CheckBox recurranceCheck = (CheckBox)
				// findViewById(R.id.checkRecurring);
				// CheckBox alarmCheck = (CheckBox)
				// findViewById(R.id.checkAlarm);

				// get name of to do
				
				EditText nameFeild = (EditText) findViewById(R.id.nameOfTodoField);

				String todoItemName = nameFeild.getText().toString();

				// toast layout setup
				LayoutInflater inflater = getLayoutInflater();
				View toastLayout = inflater.inflate(R.layout.custom_toast,
						(ViewGroup) findViewById(R.id.custom_toast_root));

				// check that todo item has a name
				if (todoItemName.equals("")) {
					((ImageView) toastLayout.findViewById(R.id.toastImg))
							.setImageResource(R.drawable.error_img);
					// setting text of custom toast message
					((TextView) toastLayout.findViewById(R.id.toastText))
							.setText("Error: Todo Item must have a name");
					Toast error = Toast.makeText(getApplicationContext(), "",
							Toast.LENGTH_LONG);
					error.setView(toastLayout);
					error.show();
				}

				// must include date in order to include a due time
				// this is mainly for purposes of sorting by due date/time
				// else if (timeCheck.isChecked() && !dateCheck.isChecked()) {
				// // displays toast message indicating that must assign a date
				//
				// ((ImageView) toastLayout.findViewById(R.id.toastImg))
				// .setImageResource(R.drawable.error_img);
				// // setting text of custom toast message
				// ((TextView) toastLayout.findViewById(R.id.toastText))
				// .setText("Error: Must assign a date to assign a time");
				// Toast dateError = Toast.makeText(getApplicationContext(),
				// "", Toast.LENGTH_LONG);
				// dateError.setView(toastLayout);
				// dateError.show();
				// }
				// everything is good, create the todo item
				else {

					// get user ID
					long userId = TodoListAccount.getInstance().getUserId();
					
					// get categoryCode
					Spinner category = (Spinner) findViewById(R.id.selectCategory);
					int categoryCode = (int) category.getSelectedItemId();
					Log.d(TAG, "Category code saved is " + categoryCode);

					Spinner recurrence = (Spinner) findViewById(R.id.selectRecurrance);
					int recurrenceCode = (int) recurrence.getSelectedItemId();

					// get todo Time in format YYYY-MM-DD'T'HH.MM.SS'Z'
					DatePicker datePicker = (DatePicker) findViewById(R.id.datePicker);
					TimePicker timePicker = (TimePicker) findViewById(R.id.timePicker);

					Date date = new Date();
					date.setDate(datePicker.getDayOfMonth());
					date.setMonth(datePicker.getMonth());
					date.setYear(datePicker.getYear());
					date.setHours(timePicker.getCurrentHour());
					date.setMinutes(timePicker.getCurrentMinute());

					Spinner alarmPriorInterval = (Spinner) findViewById(R.id.selectAlarmIncremment);
					int alarmPriorIntervalCode = (int) alarmPriorInterval
							.getSelectedItemId();
					Spinner alarmPriorIntervalAmount = (Spinner) findViewById(R.id.alarmTimePicker);
					int alarmPriorIntervalAmountCode = (int) alarmPriorIntervalAmount
							.getSelectedItemId();
					long priorValue = 0;

					if (alarmPriorIntervalCode == 0) {
						priorValue = (1000 * 60)
								* (alarmPriorIntervalAmountCode + 1);
					} else if (alarmPriorIntervalCode == 1) {
						priorValue = (1000 * 60 * 60)
								* (alarmPriorIntervalAmountCode + 1);
					} else if (alarmPriorIntervalCode == 2) {
						priorValue = (1000 * 60 * 60 * 24)
								* (alarmPriorIntervalAmountCode + 1);
					}

					// String todoTime = "";
					// String amOrPm;
					// if (true) {
					// todoTime = datePicker.getYear() + "-";
					// todoTime += datePicker.getMonth() + "-";
					// todoTime += datePicker.getDayOfMonth() + " ";
					// }
					// if (true) {
					// if (timePicker.getCurrentHour() > 12) {
					// amOrPm = "P";
					// todoTime += timePicker.getCurrentHour() - 12 + ".";
					// } else {
					// amOrPm = "A";
					// todoTime += timePicker.getCurrentHour() + ".";
					// }
					// todoTime += timePicker.getCurrentMinute() + ".00";
					// todoTime += amOrPm;
					// }
					// Log.d(TAG, "Time saved is " + todoTime);

					// TODO GOOGLE MAPS LATITUDE/ LONGITUDE STUFF WILL GO HERE (
					// both are -1 for now )
					EditText locationField = (EditText) findViewById(R.id.location);
					String location = locationField.getText().toString();
					
					float latitude = -1;
					float longitude = -1;
					
					
//					try {
//						if(!(location.equals("starting location"))){
//							List<Address> list = gc.getFromLocationName(location, 1);
//							latitude = (float) list.get(0).getLatitude();
//							longitude = (float) list.get(0).getLongitude();
//						}
//					} catch (IOException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//					
					System.out.println("lat " + latitude + " " + "long " + longitude);
					// getting todo item description
					EditText descriptionFeild = (EditText) findViewById(R.id.descriptionOfTodoField);
					String description = descriptionFeild.getText().toString();

					// TODO getting tag IDs - NOT IMPLEMENTED YET
					String tagIds = "";

					// creating the todo item
					DatabaseManager dbManager = new DatabaseManager();
					SQLiteDatabase db = dbManager.open(getApplicationContext());
					ToDoListManager todoListManager = new ToDoListManager(db);
					
					// update the item dont create a new one for edit 
					todoListManager.updateTodoListItemByTodoItemId(todoItemid, userId, todoItemName, categoryCode, date.getTime(), latitude, longitude, description, recurrenceCode, priorValue, 0);
					dbManager.close();

					// displays toast message indicating that todo item
					// sucessfully created

					// setting image of custom toast message
					((ImageView) toastLayout.findViewById(R.id.toastImg))
							.setImageResource(R.drawable.check_img);
					// setting text of custom toast message
					((TextView) toastLayout.findViewById(R.id.toastText))
							.setText("Todo Item updated");

					Toast success = Toast.makeText(getApplicationContext(), "",
							Toast.LENGTH_LONG);
					success.setView(toastLayout);
					success.show();

					// returns to main screen
					Intent myIntent = new Intent(v.getContext(),
							todoListActivity.class);
					startActivityForResult(myIntent, 3);
				}
			}
		});

		// menu button listeners
		Button menuButtonMain = (Button) findViewById(R.id.menuButtonMain);
		Button menuButtonAdd = (Button) findViewById(R.id.menuButtonAdd);
		Button menuButtonSearch = (Button) findViewById(R.id.menuButtonSearch);
		Button menuButtonSettings = (Button) findViewById(R.id.menuButtonSettings);

		// change background image of add to do menu button (current screen)
		menuButtonAdd.setBackgroundResource(R.drawable.menu_add_);

		// Set up main menu button listener
		menuButtonMain.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(),
						todoListActivity.class);
				startActivity(intent);
			}
		});

		// Set up search todo button listener
		menuButtonSearch.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(), SearchTodoList.class);
				startActivity(intent);
			}
		});

		// Set up settings button listener
		menuButtonSettings.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(v.getContext(),
						SettingsPageActivity.class);
				startActivity(intent);
			}
		});
	}
	
	void setUpLocation(boolean hasFocus){

		  if (!hasFocus) {
			  EditText locationField = (EditText) findViewById(R.id.location);
			  String location = locationField.getText().toString();
			  double latitude = -1;
			  double longitude = -1;
			  
			  if (!location.equals("") && location != null) {
						/////
						GoogleReverseGeocodeDAO reverseGeocodeResponse = null;
						//Build string with given input
						String webserviceURL = "http://maps.googleapis.com/maps/api/geocode/json?address="+location.replace(" ", "+")+"&sensor=false";
						int statusCode = -1;
						
						DefaultHttpClient httpClient = new DefaultHttpClient();
				        URI uri;
				        InputStream data = null;
				        try{
				        	//Call web service
				        	uri = new URI(webserviceURL);
				            HttpGet method = new HttpGet(uri);
				            HttpResponse response = httpClient.execute(method);
				            data = response.getEntity().getContent();
				            statusCode = response.getStatusLine().getStatusCode();
				            
				            if(statusCode == 200){
					            //Get results
					            Gson gson = new Gson();
					            Reader reader = new InputStreamReader(data);
					            reverseGeocodeResponse = gson.fromJson(reader, GoogleReverseGeocodeDAO.class);
				            }else{
				            	throw new Exception("HttpResponse status code is "+statusCode);
				            }
				       
				        }catch(Exception e){
				        	Toast.makeText(getApplicationContext(), "Error occured getting address", Toast.LENGTH_LONG).show();
							locationField.setText("");
							setLatLng(-1, -1);
				        }
						/////

						if(reverseGeocodeResponse != null && reverseGeocodeResponse.getResults() != null && reverseGeocodeResponse.getResults().size() > 0 
								&& reverseGeocodeResponse.getResults().get(0) != null 
								&& reverseGeocodeResponse.getResults().get(0).getGeometry() != null 
								&& reverseGeocodeResponse.getResults().get(0).getGeometry().getLocation() != null
								) {
							
							latitude =  reverseGeocodeResponse.getResults().get(0).getGeometry().getLocation().getLat();
							longitude = reverseGeocodeResponse.getResults().get(0).getGeometry().getLocation().getLng();
							setLatLng(latitude, longitude);
							
							String address = reverseGeocodeResponse.getResults().get(0).getFormatted_address();
							locationField.setText(address);
							
							Toast.makeText(getApplicationContext(), "Address set to closet matched address", Toast.LENGTH_LONG).show();
						}else{
							Toast.makeText(getApplicationContext(), "No matching address found for given location", Toast.LENGTH_LONG).show();
							locationField.setText("");
							setLatLng(-1, -1);
						}

				}else{
					locationField.setText("");
					setLatLng(-1, -1);
				}
		  }
	}
	
	void setLatLng(double lat, double lng){
		latitude = lat;
		longitude = lng;
	}
	
	public TodoItem retreiveToDoItem() {
		return new TodoItem();
	}
}
